package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.common.mapper.UserInfoMapper;
import com.tanhua.common.pojo.User;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.common.utils.RelativeDateFormat;
import com.tanhua.common.utils.UserThreadLocal;

import com.tanhua.dubbo.server.api.QuanZiApi;
import com.tanhua.dubbo.server.api.VisitorsApi;
import com.tanhua.dubbo.server.pojo.*;
import com.tanhua.oss.OssTemplate;
import com.tanhua.server.enums.IdType;
import com.tanhua.server.vo.CommentVo;
import com.tanhua.server.vo.PageResult;
import com.tanhua.server.vo.QuanZiVo;
import com.tanhua.server.vo.VisitorsVo;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.Serializable;
import java.util.*;

@Service
public class QuanZiService {

    @Reference
    private QuanZiApi quanZiApi;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private IdService idService;

    @Autowired
    private TimeLineService timeLineService;

    @Reference(version = "1.0.0")
    private VisitorsApi visitorsApi;

    @Autowired
    private BlackUserService blackUserService;

    //查询好友动态
    public PageResult queryFriendList(Integer page, Integer pagesize) {
        //1、token校验
        User user = UserThreadLocal.get();
        //2、当前登录者：user.getId()
        //登录者id到时间线表中查询动态id,动态id到动态表中查询动态信息
        List<TimeLine> timeLinelist = quanZiApi.queryTimeLine(user.getId());
        //使用hutool工具，从指定集合的具体属性组装成集合
        List<Object> publishIds = CollUtil.getFieldValues(timeLinelist, "publishId");
        List<Publish> publishList = quanZiApi.queryPublishList(publishIds, page, pagesize);
        List<QuanZiVo> list = new ArrayList<>();
        //遍历所有动态
        for (Publish publish : publishList) {
            QuanZiVo quanZiVo = new QuanZiVo();
            quanZiVo.setId(publish.getId().toHexString());
            quanZiVo.setUserId(publish.getUserId());
            quanZiVo.setTextContent(publish.getText());
            quanZiVo.setImageContent(publish.getMedias().toArray(new String[]{}));
            quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
            //根据用户id查询用户信息
            LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserInfo::getUserId, publish.getUserId());
            UserInfo userInfo = userInfoMapper.selectOne(wrapper);
            fillUserInfoToQuanZiVo(userInfo, quanZiVo);
            list.add(quanZiVo);
        }

        PageResult result = new PageResult();
        result.setPage(page);
        result.setPagesize(pagesize);
        result.setItems(list);
        return result;
    }

    //填充用户信息
    private void fillUserInfoToQuanZiVo(UserInfo userInfo, QuanZiVo quanZiVo) {
        BeanUtil.copyProperties(userInfo, quanZiVo, "id");
        quanZiVo.setNickname(userInfo.getNickName()); //昵称
        quanZiVo.setAvatar(userInfo.getLogo());//头像
        quanZiVo.setGender(userInfo.getSex().name().toLowerCase());
        quanZiVo.setTags(StringUtils.split(userInfo.getTags(), ','));
        quanZiVo.setCommentCount(0); //TODO 评论数
        quanZiVo.setDistance("1.2公里"); //TODO 距离
        User user = UserThreadLocal.get();
        quanZiVo.setHasLiked(quanZiApi.queryUserIsLike(user.getId(), quanZiVo.getId()) ? 1 : 0); //TODO 是否点赞（1是，0否）
        quanZiVo.setLikeCount(Convert.toInt(quanZiApi.queryLikeCount(quanZiVo.getId()))); //TODO 点赞数
        quanZiVo.setHasLoved(quanZiApi.queryUserIsLove(user.getId(), quanZiVo.getId()) ? 1 : 0); //TODO 是否喜欢（1是，0否）
        quanZiVo.setLoveCount(Convert.toInt(quanZiApi.queryLoveCount(quanZiVo.getId()))); //TODO 喜欢数
        quanZiVo.setCommentCount(Convert.toInt(quanZiApi.queryCommentCount(quanZiVo.getId()))); //TODO 评论数

    }

    //查询推荐
    public PageResult queryRecommendList(Integer page, Integer pagesize) {
        //1、token校验
        User user = UserThreadLocal.get();

        String redisKey = "QUANZI_PUBLISH_RECOMMEND_" + user.getId();
        String redisData = redisTemplate.opsForValue().get(redisKey);//'1,2,3...'

        String[] split = StrUtil.split(redisData, ",");
        List<Long> pidLongList = new ArrayList<>();
        for (String pid : split) {
            pidLongList.add(Long.valueOf(pid));
        }
        //获取推荐集合
        List<Publish> publishList = quanZiApi.queryRecommendList(pidLongList, page, pagesize);
        List<QuanZiVo> list = new ArrayList<>();
        //遍历所有动态
        for (Publish publish : publishList) {
            //加入黑名单过滤
            List<Long> longs = blackUserService.queryAllBlackUser();
            //判断推荐用户中是否存在黑名单用户
            if (!longs.contains(publish.getUserId())) {
                QuanZiVo quanZiVo = new QuanZiVo();
                quanZiVo.setId(publish.getId().toHexString());
                quanZiVo.setUserId(publish.getUserId());
                quanZiVo.setTextContent(publish.getText());
                quanZiVo.setImageContent(publish.getMedias().toArray(new String[]{}));
                quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
                //根据用户id查询用户信息
                LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(UserInfo::getUserId, publish.getUserId());
                UserInfo userInfo = userInfoMapper.selectOne(wrapper);
                fillUserInfoToQuanZiVo(userInfo, quanZiVo);
                list.add(quanZiVo);
            }
        }

        PageResult result = new PageResult();
        result.setPage(page);
        result.setPagesize(pagesize);
        result.setItems(list);
        return result;
    }

    //发布动态
    public void savePublish(String textContent, String location, String latitude, String longitude, MultipartFile[] multipartFile) {
        //1、token校验
        User user = UserThreadLocal.get();
        //2、发布表新增
        Publish publish = new Publish();
        publish.setId(new ObjectId());
        publish.setText(textContent);
        publish.setLocationName(location);
        publish.setLatitude(latitude);
        publish.setLongitude(longitude);
        //上传图片阿里云
        List<String> list = ossTemplate.uploads(multipartFile);
        publish.setMedias(list);
        publish.setUserId(user.getId());
        publish.setPid(idService.createId(IdType.PUBLISH));
        publish.setSeeType(1);
        publish.setCreated(System.currentTimeMillis());
        publish.setState(3);
        quanZiApi.savePublish(publish);
        //3、相册表新增
        Album album = new Album();
        album.setPublishId(publish.getId());
        album.setCreated(System.currentTimeMillis());
        quanZiApi.saveAlbum(album, user.getId());
        //4、好友时间线表新增  查询好友 userId:登录者id  friendId:好友id(需要)
        timeLineService.saveTimeLine(user.getId(), publish);//异步执行

    }

    //动态点赞
    public Long likeComment(String publishId) {
        //解析token
        User user = UserThreadLocal.get();
        //点赞
        Boolean result = quanZiApi.likeComment(user.getId(), publishId);
        if (result) {
            //查询点赞数
            return quanZiApi.queryLikeCount(publishId);
        }
        return null;
    }

    //取消动态点赞
    public Long dislikeComment(String publishId) {
        //解析token
        User user = UserThreadLocal.get();
        //取消点赞
        Boolean result = quanZiApi.disLikeComment(user.getId(), publishId);
        if (result) {
            //查询点赞数
            return quanZiApi.queryLikeCount(publishId);
        }
        return null;
    }

    //动态喜欢
    public Long loveComment(String publishId) {
        //解析token
        User user = UserThreadLocal.get();
        //点赞
        Boolean result = quanZiApi.loveComment(user.getId(), publishId);
        if (result) {
            //查询喜欢数
            return quanZiApi.queryLoveCount(publishId);
        }
        return null;
    }

    //取消动态喜欢
    public Long disLoveComment(String publishId) {
        //解析token
        User user = UserThreadLocal.get();
        //取消喜欢
        Boolean result = quanZiApi.disLoveComment(user.getId(), publishId);
        if (result) {
            //查询喜欢数
            return quanZiApi.queryLoveCount(publishId);
        }
        return null;
    }

    //查询单条动态
    public QuanZiVo queryById(String publishId) {
        Publish publish = this.quanZiApi.queryPublishById(publishId);
        if (publish == null) {
            return null;
        }
        QuanZiVo quanZiVo = new QuanZiVo();
        quanZiVo.setId(publish.getId().toHexString());
        quanZiVo.setUserId(publish.getUserId());
        quanZiVo.setTextContent(publish.getText());
        quanZiVo.setImageContent(publish.getMedias().toArray(new String[]{}));
        quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
        UserInfo userInfo = userInfoMapper.selectById(publish.getUserId());
        fillUserInfoToQuanZiVo(userInfo, quanZiVo);
        return quanZiVo;
    }

    //查询评论列表
    public PageResult queryCommentList(String publishId, Integer page, Integer pageSize) {
        //1、token校验
        User user = UserThreadLocal.get();
        //2 定义一个PageResult 封装分页参数
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        //根据动态id和评论的类型查询评论列表
        List<Comment> commentList = quanZiApi.queryCommentList(publishId, page, pageSize);
        if (CollUtil.isEmpty(commentList)) {
            return pageResult;
        }
        //查询用户信息
        List<Object> userIdList = CollUtil.getFieldValues(commentList, "userId");
        List<UserInfo> userInfoList = queryUserInfoByUserIdList(userIdList);
        List<CommentVo> commentVos = new ArrayList<>();
        //封装commentVo,将userInfo和comment信息填充到commentVo
        for (Comment comment : commentList) {
            //加入黑名单过滤
            List<Long> longs = blackUserService.queryAllBlackUser();
            if (!longs.contains(comment.getUserId())) {
                CommentVo commentVo = new CommentVo();
                commentVo.setId(comment.getId().toHexString());
                commentVo.setContent(comment.getContent());
                commentVo.setCreateDate(DateUtil.format(new Date(comment.getCreated()), "HH:mm"));
                //评论的点赞数
                commentVo.setLikeCount(Convert.toInt(quanZiApi.queryLikeCount(commentVo.getId())));
                //判断登陆者是否给评论点赞了
                commentVo.setHasLiked(quanZiApi.queryUserIsLike(user.getId(), commentVo.getId()) ? 1 : 0);
                //将userInfo信息填充到commentVo
                for (UserInfo userInfo : userInfoList) {
                    //如果评论人id和评论列表中id相同 则赋值评论人昵称和头像
                    if (ObjectUtil.equals(comment.getUserId(), userInfo.getUserId())) {
                        commentVo.setAvatar(userInfo.getLogo());
                        commentVo.setNickname(userInfo.getNickName());
                        break;
                    }
                }
                commentVos.add(commentVo);
            }
        }
        //将commentVo信息填充到pageResult中响应给页面
        pageResult.setItems(commentVos);
        return pageResult;
    }

    //通过userId查询userInfo表
    public List<UserInfo> queryUserInfoByUserIdList(List<Object> userIdList) {
        List<UserInfo> userInfoList = new ArrayList<>();
        //根据userID查询UserInfo
        for (Object userId : userIdList) {
            UserInfo userInfo = userInfoMapper.selectById((Serializable) userId);
            userInfoList.add(userInfo);
        }
        return userInfoList;
    }

    //保存评论
    public boolean saveComments(String publishId, String comment) {
        //1. 解析token
        User user = UserThreadLocal.get();
        //2. 调用保存
        return quanZiApi.saveComment(user.getId(), publishId, comment);
    }

    //查看相册列表
    public PageResult queryAlbumList(Long userId, Integer page, Integer pageSize) {
        //2.获取到用户的所有动态
        List<Publish> publishes = quanZiApi.queryAlbumList(userId, page, pageSize);
        //3.新建一个存放返回前端数据的聚合
        List<QuanZiVo> list = new ArrayList<>();
        //4.遍历所有动态集合并封装到新集合中
        for (Publish publish : publishes) {
            QuanZiVo quanZiVo = new QuanZiVo();
            quanZiVo.setId(publish.getId().toHexString());
            quanZiVo.setUserId(publish.getUserId());
            quanZiVo.setTextContent(publish.getText());
            List<String> medias = publish.getMedias();
            quanZiVo.setImageContent(medias.toArray(new String[]{}));
            quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
            //根据用户id查询用户信息
            LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserInfo::getUserId, publish.getUserId());
            UserInfo userInfo = userInfoMapper.selectOne(wrapper);
            fillUserInfoToQuanZiVo(userInfo, quanZiVo);
            list.add(quanZiVo);
        }

        PageResult result = new PageResult();
        result.setPage(page);
        result.setPagesize(pageSize);
        result.setItems(list);
        return result;
    }

    //查看访客列表
    public List<VisitorsVo> queryVisitorsList() {
        User user = UserThreadLocal.get();
        List<Visitors> visitorsList = this.visitorsApi.queryMyVisitor(user.getId());

        List<Object> userIds = CollUtil.getFieldValues(visitorsList, "visitorUserId");
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.in("user_id", userIds);
        List<UserInfo> userInfoList = this.userInfoMapper.selectList(wrapper);
        List<VisitorsVo> visitorsVoList = new ArrayList<>();
        for (Visitors visitor : visitorsList) {
            //加入黑名单过滤
            List<Long> longs = blackUserService.queryAllBlackUser();
            if (!longs.contains(visitor.getVisitorUserId())) {
                for (UserInfo userInfo : userInfoList) {
                    if (ObjectUtil.equals(visitor.getVisitorUserId(), userInfo.getUserId())) {

                        VisitorsVo visitorsVo = new VisitorsVo();
                        visitorsVo.setAge(userInfo.getAge());
                        visitorsVo.setAvatar(userInfo.getLogo());
                        visitorsVo.setGender(userInfo.getSex().name().toLowerCase());
                        visitorsVo.setId(userInfo.getUserId());
                        visitorsVo.setNickname(userInfo.getNickName());
                        visitorsVo.setTags(StringUtils.split(userInfo.getTags(), ','));
                        visitorsVo.setFateValue(visitor.getScore().intValue());

                        visitorsVoList.add(visitorsVo);
                        break;
                    }
                }

            }
        }

        return visitorsVoList;
    }
}
